/*
 * Powered By XY
 * Since 2020
 */

package com.xy.biz.xd.manager.impl;

import com.xy.biz.fd.client.DocumentClient;
import com.xy.biz.fd.domain.resp.GetDocumentResponse;
import com.xy.biz.uc.client.UserClient;
import com.xy.biz.xd.dao.DocumentFlowNewAndModifyDao;
import com.xy.biz.xd.domain.bo.DocumentFlowBO;
import com.xy.biz.xd.domain.bo.DocumentFlowConstants;
import com.xy.biz.xd.domain.bo.DocumentFlowNewAndModifyBO;
import com.xy.biz.xd.domain.converter.DocumentFlowNewAndModifyConverter;
import com.xy.biz.xd.domain.po.DocumentFlowNewAndModifyPO;
import com.xy.biz.xd.domain.po.DocumentFlowPO;
import com.xy.biz.xd.domain.query.DocumentFlowNewAndModifyQuery;
import com.xy.biz.xd.domain.query.DocumentFlowQuery;
import com.xy.biz.xd.manager.DocumentFlowManager;
import com.xy.biz.xd.manager.DocumentFlowNewAndModifyManager;
import com.xy.tool.util.BeanUtilsEx;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;


/**
 *
 *
 * @author wcs
 * @date 2021-2-26
 */
@Service
public class DocumentFlowNewAndModifyManagerImpl implements DocumentFlowNewAndModifyManager {

    @Autowired
    private DocumentFlowNewAndModifyDao documentFlowNewAndModifyDao;
    @Autowired
    private DocumentFlowManager documentFlowManager;
    @Autowired
    private UserClient userClient;
    @Autowired
    private DocumentClient documentClient;

    @Transactional
    @Override
    public int saveDocumentFlowNewAndModify(DocumentFlowNewAndModifyBO documentFlowNewAndModifyBO) {
        int affectedRows = documentFlowNewAndModifyDao.saveDocumentFlowNewAndModify(DocumentFlowNewAndModifyConverter.toPO(documentFlowNewAndModifyBO));
        if (affectedRows > 0) {
            documentFlowManager.saveDocumentFlow(documentFlowNewAndModifyBO);
        }
        return affectedRows;
    }

    @Transactional
    @Override
    public int saveAllDocumentFlowNewAndModify(List<DocumentFlowNewAndModifyBO> documentFlowNewAndModifyBOList) {
        int affectedRows = documentFlowNewAndModifyDao.saveAllDocumentFlowNewAndModify(DocumentFlowNewAndModifyConverter.toPO(documentFlowNewAndModifyBOList));
        if (affectedRows > 0) {
            documentFlowManager.saveAllDocumentFlow(new ArrayList<>(documentFlowNewAndModifyBOList));
        }
        return affectedRows;
    }

    @Override
    public int updateDocumentFlowNewAndModify(DocumentFlowNewAndModifyBO documentFlowNewAndModifyBO) {
        int affectedRows = documentFlowNewAndModifyDao.updateDocumentFlowNewAndModify(DocumentFlowNewAndModifyConverter.toPO(documentFlowNewAndModifyBO));
        if (affectedRows > 0) {
            documentFlowManager.updateDocumentFlow(documentFlowNewAndModifyBO);
            if (DocumentFlowConstants.PHASE_RELEASE.equals(documentFlowNewAndModifyBO.getPhase())) {
                List<DocumentFlowBO> documentFlowBOList =
                        documentFlowManager.listDocumentFlow(DocumentFlowQuery.max().parentDocumentFlowId(documentFlowNewAndModifyBO.getDocumentFlowId()).build());
                if (!CollectionUtils.isEmpty(documentFlowBOList)) {
                    List<DocumentFlowNewAndModifyPO> documentFlowNewAndModifyPOList = new ArrayList<>();
                    documentFlowBOList.forEach(e -> {
                        e.setPhase(DocumentFlowConstants.PHASE_RELEASE);
                        e.setUpdateTime(LocalDateTime.now());
                        documentFlowNewAndModifyPOList.add(DocumentFlowNewAndModifyPO.builder()
                                .documentFlowId(e.getDocumentFlowId())
                                .trainFlag(documentFlowNewAndModifyBO.getTrainFlag())
                                .trainCheckStatus(documentFlowNewAndModifyBO.getTrainCheckStatus())
                                .trainCheckTime(documentFlowNewAndModifyBO.getTrainCheckTime())
                                .trainerUserId(documentFlowNewAndModifyBO.getTrainerUserId())
                                .build());
                    });
                    documentFlowNewAndModifyDao.updateAllDocumentFlowNewAndModify(documentFlowNewAndModifyPOList);
                    documentFlowManager.updateAllDocumentFlow(documentFlowBOList);
                }
            }
        }
        return affectedRows;
    }

    @Override
    public int updateAllDocumentFlowNewAndModify(List<DocumentFlowNewAndModifyBO> documentFlowNewAndModifyBOList) {
        int affectedRows = documentFlowNewAndModifyDao.updateAllDocumentFlowNewAndModify(DocumentFlowNewAndModifyConverter.toPO(documentFlowNewAndModifyBOList));
        if (affectedRows > 0) {
            documentFlowManager.updateAllDocumentFlow(new ArrayList<>(documentFlowNewAndModifyBOList));
        }
        return affectedRows;
    }

    @Override
    public DocumentFlowNewAndModifyBO getDocumentFlowNewAndModify(Long documentFlowId) {
        DocumentFlowNewAndModifyBO documentFlowNewAndModifyBO = DocumentFlowNewAndModifyConverter.fromPO(documentFlowNewAndModifyDao.getDocumentFlowNewAndModify(documentFlowId));
        if (documentFlowNewAndModifyBO != null) {
            DocumentFlowBO documentFlowBO = documentFlowManager.getDocumentFlow(documentFlowId);
            if (documentFlowBO != null) {
                BeanUtilsEx.copyProperties(documentFlowBO, documentFlowNewAndModifyBO);
            }
        }
        return documentFlowNewAndModifyBO;
    }

    @Override
    public void updateReviewerNum(DocumentFlowBO documentFlowBO, int reviewerNum) {
        documentFlowNewAndModifyDao.updateDocumentFlowNewAndModify(DocumentFlowNewAndModifyPO.builder().documentFlowId(documentFlowBO.getDocumentFlowId()).reviewerNum(reviewerNum).build());
    }

    @Override
    public int getReviewerNum(DocumentFlowBO documentFlowBO) {
        DocumentFlowNewAndModifyPO documentFlowNewAndModifyPO = documentFlowNewAndModifyDao.getDocumentFlowNewAndModify(documentFlowBO.getDocumentFlowId());
        return documentFlowNewAndModifyPO.getReviewerNum();
    }

    @Override
    public List<DocumentFlowNewAndModifyBO> listDocumentFlowNewAndModify(DocumentFlowNewAndModifyQuery query) {
        List<DocumentFlowNewAndModifyBO> documentFlowNewAndModifyBOList = DocumentFlowNewAndModifyConverter.fromPO(documentFlowNewAndModifyDao.listDocumentFlowNewAndModify(query));
        if (!CollectionUtils.isEmpty(documentFlowNewAndModifyBOList)) {
            userClient.buildByUser(
                    documentFlowNewAndModifyBOList,
                    documentFlowNewAndModifyBOList.stream().map(DocumentFlowNewAndModifyBO::getTrainerUserId).collect(Collectors.toList()),
                    DocumentFlowNewAndModifyBO::getTrainerUserId,
                    (documentFlowNewAndModifyBO, userDTO) -> documentFlowNewAndModifyBO.setTrainerUserName(userDTO.getUserName())
            );
            Set<Long> documentFlowIdSet = documentFlowNewAndModifyBOList.stream().map(DocumentFlowNewAndModifyBO::getDocumentFlowId).collect(Collectors.toSet());
            List<DocumentFlowBO> documentFlowBOList = documentFlowManager.listDocumentFlowById(documentFlowIdSet);
            /*documentClient.buildByDocument(
                    documentFlowBOList,
                    documentFlowBOList.stream().map(DocumentFlowBO::getDocumentId).collect(Collectors.toList()),
                    DocumentFlowBO::getDocumentId,
                    (doc, getDocumentResponse) -> doc.setDocumentName(getDocumentResponse.getDocumentName() + getDocumentResponse.getFileExtension())
            );*/
            if (!CollectionUtils.isEmpty(documentFlowBOList)) {
                Map<Long, DocumentFlowBO> documentFlowBOMap = documentFlowBOList.stream().collect(Collectors.toMap(DocumentFlowBO::getDocumentFlowId, e -> e));
                for (DocumentFlowNewAndModifyBO documentFlowNewAndModifyBO : documentFlowNewAndModifyBOList) {
                    DocumentFlowBO documentFlowBO = documentFlowBOMap.get(documentFlowNewAndModifyBO.getDocumentFlowId());
                    if (documentFlowBO != null) {
                        BeanUtilsEx.copyProperties(documentFlowBO, documentFlowNewAndModifyBO);
                    }
                }
            }
        }
        return documentFlowNewAndModifyBOList;
    }

    @Override
    public int countDocumentFlowNewAndModify(DocumentFlowNewAndModifyQuery query) {
        return documentFlowNewAndModifyDao.countDocumentFlowNewAndModify(query);
    }

    @Override
    public List<DocumentFlowNewAndModifyBO> getDocumentFlowNewAndModifyList(Collection<Long> collect) {
        return DocumentFlowNewAndModifyConverter.fromPO(documentFlowNewAndModifyDao.getDocumentFlowNewAndModifyList(collect));
    }

}
